﻿using SelfManagement.Web.Infrastructure;
using SelfManagement.Web.Models.ViewModels.DailyModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SelfManagement.Utility.Extensions;
using SelfManagement.Database.POCO;
using Ninject;
using SelfManagement.IServices;
using SelfManagement.Utility.Helper;
using SelfManagement.Mvc.Result;
using SelfManagement.Mvc.Helper;
using MvcPaging;

namespace SelfManagement.Web.Controllers
{
    [UserAuthorize]
    public class DailyController : CommonBaseController
    {
        [Inject]
        public IDailyService DailyService { get; set; }
        [Inject]
        public IBaseService<DailyTask> DailyTaskService { get; set; }

        // GET: Daily
        public ActionResult Index(DailyPagedListModel viewModel)
        {
            IQueryable<Daily> query = DailyService.QueryUserDailies(UserSession.Identity);
            if (viewModel.Keyword.IsNotNullAndNotWhiteSpace())
            {
                var key = viewModel.Keyword;
                query = query.Where(d => d.TaskName.Contains(key)) // 搜索任务名称
                             .Where(d => d.Tasks.Count(t => t.TaskName.Contains(key)) > 0) // 搜索子任务
                             .Where(d => d.Performance.Contains(key)); // 搜索表现
            }
            if (viewModel.Date.HasValue)
            {
                query = query.Where(d => d.Date == viewModel.Date); // 搜索日期
            }
            if (viewModel.Status.HasValue)
            {
                query = query.Where(d => d.Status == viewModel.Status); // 搜索任务状态
            }

            viewModel.PagedList = query.OrderByDescending(m => m.Date)
                                       .ToPagedList(viewModel.PageIndex, viewModel.Size);

            viewModel.QueryParameter = GetParameterFromQueryString();
            viewModel.TaskStatusSelectItems = SelectListItemsHelper.FromEnum(
                typeof(TaskStatus), extraFirstItem: "全部").ToList();
            SetPageTitle("每日计划");
            SetBreadcrumb("每日计划");
            return View(viewModel);
        }

        /// <summary>
        /// 今日任务
        /// </summary>
        /// <returns></returns>
        public ActionResult Today()
        {
            Daily today = DailyService.GetUserToday(UserSession.Identity);
            if (today.IsNull())
            {
                return RedirectToAction("CreateOrEdit");
            }
            return RedirectToAction("CreateOrEdit", new { id = today.Id });
        }

        /// <summary>
        /// 新增或修改每日计划
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult CreateOrEdit(string id)
        {
            DailyViewModel viewModel = new DailyViewModel();
            Daily daily = DailyService.GetUserDaily(UserSession.Identity, id);
            viewModel.IsEdit = daily.IsNotNull();
            daily = daily ?? new Daily() { TaskName = DateTime.Now.ToString("yyyy年MM月dd日计划")};
            DailyModelTransform(daily, viewModel, true);
            if(!viewModel.IsEdit)
                viewModel.Date = DateTime.Now;
            string title = (viewModel.IsEdit ? "编辑" : "新建") + "计划";
            SetPageTitle(title);
            SetBreadcrumb(title, parentName: "每日计划", parentUrl: Url.Action("Index"));
            return View(viewModel);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        public ActionResult CreateOrEdit(DailyViewModel post)
        {
            JsonResultData result = new JsonResultData();
            result.RunWithTry(data =>
            {
                if (ModelState.IsValid)
                {
                    Daily daily = post.IsEdit
                                        ? DailyService.GetUserDaily(UserSession.Identity, post.Id)
                                        : new Daily();
                    if (DailyService.IsExistDateOfDaily(daily.Id, UserSession.Identity, post.Date))
                    {
                        result.AddMessage(post.Date.ToLocalYYYYMMDD() + "已存在任务");
                        return;
                    }
                    DailyModelTransform(daily, post, false);
                    if (post.IsEdit)
                    {
                        daily.SetUpdateInfo(UserSession.UserEntity.TrueName);
                        DailyService.Update(daily);
                    }
                    else
                    {
                        daily.SetCreateAndUpdateInfo(UserSession.UserEntity.TrueName);
                        DailyService.Insert(daily);
                    }
                    result.RedirectUrl = Url.Action("Index");
                    result.AddMessage("保存成功！");
                    result.Success = true;
                }
                else
                {
                    result.AddModelValidErrorMessage(ModelState);
                }
            });
            return Json(result);
        }

        /// <summary>
        /// 删除日常任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Delete(string id)
        {
            JsonResultData result = new JsonResultData();
            result.RunWithTry(data =>
            {
                if (ModelState.IsValid)
                {
                    result.Success = DailyService.DeleteUserDailyById(UserSession.Identity, id);
                    result.AddMessage("删除" + (result.Success ? "成功" : "失败"));
                    result.ReloadPage = result.Success;
                }
                else
                {
                    result.AddModelValidErrorMessage(ModelState);
                }
            });
            return Json(result);
        }

        private void DailyModelTransform(Daily daily, DailyViewModel model, bool isView)
        {
            if (isView)
            {
                ValueCopyHelper.CopyProperty(model, daily, false,
                    nameof(daily.Id),
                    nameof(daily.TaskName),
                    nameof(daily.Date),
                    nameof(daily.Performance));
                model.Tasks = daily.Tasks;
                if(daily.Status != TaskStatus.Deffered)
                {
                    model.IsCompledted = daily.Status == TaskStatus.Completed;
                }
            }
            else
            {
                ValueCopyHelper.CopyProperty(daily, model, false,
                    nameof(model.Id),
                    nameof(model.TaskName),
                    nameof(model.Date),
                    nameof(model.Performance));
                List<DailyTask> tasks = model.TasksJson.ToObject<List<DailyTask>>();
                if (model.IsEdit)
                {
                    var oldTasks = daily.Tasks.ToList();
                    var oldTaskIds = oldTasks.Select(t => t.Id).ToList();
                    //oldTasks.ForEach(t => daily.Tasks.Remove(t));
                    DailyTaskService.DeleteBatch(t => oldTaskIds.Contains(t.Id));
                }

                int order = 1;
                tasks.ForEach(t =>
                {
                    daily.Tasks.Add(new DailyTask()
                    {
                        Status = t.Status,
                        TaskName = t.TaskName.Trim(),
                        EstimateTime = t.EstimateTime,
                        Order = order++
                    });
                });

                if (daily.Status != TaskStatus.Deffered)
                {
                    daily.Status = model.IsCompledted ? TaskStatus.Completed : TaskStatus.Uncompleted;
                }
                daily.User_Id = UserSession.Identity;
            }
        }
    }
}